﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;

namespace Mongoose.Windows.Controls
{
    /// <summary>
    /// Control Bar for a Pad control
    /// </summary>
    [TemplatePart(Name = "PART_Thumb", Type = typeof(Thumb))]
    [TemplatePart(Name = "PART_CloseButton", Type = typeof(Button))]
    [TemplatePart(Name = "PART_PinToggleButton", Type = typeof(PathToggleButton))]
    public class PadControlBar : Control
    {
        /// <summary>
        /// Initializes the <see cref="PadControlBar"/> class.
        /// </summary>
        static PadControlBar()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(PadControlBar), new FrameworkPropertyMetadata(typeof(PadControlBar)));
            PadControlBar.StyleProperty.OverrideMetadata(typeof(PadControlBar), new FrameworkPropertyMetadata(DefaultStyle));
            PadControlBar.TemplateProperty.OverrideMetadata(typeof(PadControlBar), new FrameworkPropertyMetadata(DefaultTemplate));
        }

        /// <summary>
        /// When overridden in a derived class, is invoked whenever application code or internal processes call <see cref="M:System.Windows.FrameworkElement.ApplyTemplate" />.
        /// </summary>
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            Thumb.DragDelta += OnDragDelta;
            CloseButton.Click += OnCloseButtonClick;
            PinToggleButton.Click += OnPinToggleButtonClick;
        }

        /// <summary>
        /// Called on DragDelta event on the underlying Thumb object.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="DragDeltaEventArgs"/> instance containing the event data.</param>
        private static void OnDragDelta(object sender, DragDeltaEventArgs e)
        {
            if (!Keyboard.IsKeyDown(Key.LeftCtrl))
            {
                var thumb = sender as Thumb;
                if (thumb == null)
                {
                    throw new InvalidOperationException();
                }
                var pad = thumb.Tag as Pad;
                if (pad == null)
                {
                    throw new InvalidOperationException();
                }

                var container = pad.Container;
                IPadContainerLayout layout = null;
                if (container != null)
                {
                    layout = container.Layout;
                }

                if (!pad.IsPinned && !container.HasDynamicLayout)
                {
                    var positionChange = new Point(e.HorizontalChange, e.VerticalChange);
                    var currentPosition = pad.Position;
                    pad.Position = new Point(currentPosition.X + positionChange.X, currentPosition.Y + positionChange.Y);
                }
            }
        }

        /// <summary>
        /// Called when [close button click].
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
        void OnCloseButtonClick(object sender, RoutedEventArgs e)
        {
            Pad.Close();
        }

        /// <summary>
        /// Called when [pin toggle button click].
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
        void OnPinToggleButtonClick(object sender, RoutedEventArgs e)
        {
            Pad.SwitchPinMode();
        }

        /// <summary>
        /// Gets the thumb used to manage Pad Move operations.
        /// </summary>
        /// <value>
        /// The thumb.
        /// </value>
        internal Thumb Thumb
        {
            get
            {
                if (thumb == null)
                {
                    thumb = GetTemplateChild("PART_Thumb") as Thumb;
                    thumb.Tag = Pad;
                }
                return thumb;
            }
        }

        /// <summary>
        /// Gets the close button.
        /// </summary>
        /// <value>
        /// The close button.
        /// </value>
        internal Button CloseButton
        {
            get
            {
                if (closeButton == null)
                {
                    closeButton = GetTemplateChild("PART_CloseButton") as Button;
                }
                return closeButton;
            }
        }

        internal PathToggleButton PinToggleButton
        {
            get
            {
                if (pinToggleButton == null)
                {
                    pinToggleButton = GetTemplateChild("PART_PinToggleButton") as PathToggleButton;
                }
                return pinToggleButton;
            }
        }

        internal Pad Pad
        {
            get
            {
                if (pad == null)
                {
                    pad = this.SafeFindAncestor<Pad>();
                }
                return pad;
            }
        }

        protected static Style DefaultStyle
        {
            get
            {
                if (defaultStyle == null)
                {
                    defaultStyle = Application.Current.TryFindResource("PadControlBarDefaultStyle") as Style;
                }
                return defaultStyle;
            }
        }

        protected static ControlTemplate DefaultTemplate
        {
            get
            {
                if (defaultTemplate == null)
                {
                    defaultTemplate = Application.Current.TryFindResource("PadControlBarDefaultTemplate") as ControlTemplate;
                }
                return defaultTemplate;
            }
        }

        #region Private fields
        private Thumb thumb;
        private Pad pad;
        private Button closeButton;
        private PathToggleButton pinToggleButton;

        private static Style defaultStyle;
        private static ControlTemplate defaultTemplate;
        #endregion
    }
}
